home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / vbcc.lha / vbcc / ic.c < prev    next >
C/C++ Source or Header  |  1998-02-17  |  52KB  |  1,467 lines

  1. /*  $VER: vbcc (ic.c) V0.4  */
  2.  
  3. #include "vbc.h"
  4.  
  5. static char FILE_[]=__FILE__;
  6.  
  7.  
  8. int do_arith(np,struct IC *,np,struct obj *);
  9.  
  10. void gen_test(struct obj *o,int t,int branch,int label)
  11. /*  Generiert ein test o, branch label und passt auf, dass      */
  12. /*  kein TEST const generiert wird.                             */
  13. {
  14.     struct IC *new;
  15.     if(o->flags&KONST){
  16.         eval_const(&o->val,t);
  17.         if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))){
  18.             if(branch==BEQ) branch=BRA; else branch=0;
  19.         }else{
  20.             if(branch==BNE) branch=BRA; else branch=0;
  21.         }
  22.     }else{
  23.         new=mymalloc(ICS);
  24.         new->code=TEST;
  25.         new->q2.flags=new->z.flags=0;
  26.         new->typf=t;
  27.         new->q1=*o;
  28.         add_IC(new);
  29.     }
  30.     if(branch){
  31.         new=mymalloc(ICS);
  32.         new->code=branch;
  33.         new->typf=label;
  34.         add_IC(new);
  35.     }
  36. }
  37.  
  38. void inline_memcpy(np z,np q,zlong size)
  39. /*  fuegt ein ASSIGN-IC ein, das memcpy(z,q,size) entspricht    */
  40. {
  41.     struct IC *new=mymalloc(ICS);
  42.     if((z->ntyp->flags&NQ)!=POINTER) ierror(0);
  43.     if((q->ntyp->flags&NQ)!=POINTER) ierror(0);
  44.  
  45.     gen_IC(z,0,0);
  46.     if(z->o.flags&DREFOBJ){
  47.         struct IC *n2=mymalloc(ICS);
  48.         n2->code=ASSIGN;
  49.         n2->typf=q->ntyp->flags;
  50.         n2->q1=z->o;
  51.         get_scratch(&n2->z,z->ntyp->flags,z->ntyp->next->flags,z->ntyp);
  52.         n2->q2.flags=0;
  53.         n2->q2.val.vlong=sizetab[POINTER];
  54.         new->z=n2->z;
  55.         add_IC(n2);
  56.     }else{
  57.         new->z=z->o;
  58.     }
  59.     if(new->z.flags&VARADR) new->z.flags&=~VARADR; else new->z.flags|=DREFOBJ;
  60.  
  61.     gen_IC(q,0,0);
  62.     if(q->o.flags&DREFOBJ){
  63.         struct IC *n2=mymalloc(ICS);
  64.         n2->code=ASSIGN;
  65.         n2->typf=q->ntyp->flags;
  66.         n2->q1=q->o;
  67.         get_scratch(&n2->z,q->ntyp->flags,q->ntyp->next->flags,q->ntyp);
  68.         n2->q2.flags=0;
  69.         n2->q2.val.vlong=sizetab[POINTER];
  70.         new->q1=n2->z;
  71.         add_IC(n2);
  72.     }else{
  73.         new->q1=q->o;
  74.     }
  75.     if(new->q1.flags&VARADR) new->q1.flags&=~VARADR; else new->q1.flags|=DREFOBJ;
  76.  
  77.     new->code=ASSIGN;
  78.     new->typf=UNSIGNED|CHAR;
  79.     new->q2.flags=0;
  80.     new->q2.val.vlong=size;
  81.     add_IC(new);
  82. }
  83.  
  84. void add_IC(struct IC *new)
  85. /*  fuegt ein IC ein                                            */
  86. {
  87.     int code;
  88.     if(!new) return;
  89.     if(nocode) {free(new);return;}
  90.     new->next=0;
  91.     new->q1.am=new->q2.am=new->z.am=0;
  92.     new->line=line; new->file=0;
  93.     code=new->code;
  94.     if(code>=BEQ&&code<=BRA) new->q1.flags=new->q2.flags=new->z.flags=0;
  95.     if(code==ALLOCREG||code==FREEREG||code==SAVEREGS||code==RESTOREREGS) new->typf=0;
  96.     if(DEBUG&64){ pric(stdout,first_ic);printf("new\n");pric2(stdout,new);printf("-\n");}
  97.     if(new->q1.flags&VAR){
  98.         if(!new->q1.v) ierror(0);
  99.         new->q1.v->flags|=USEDASSOURCE;
  100.         if(code==ADDRESS||(new->q1.flags&VARADR)) new->q1.v->flags|=USEDASADR;
  101.         new->q1.v->priority+=currentpri;
  102.     }
  103.     if(new->q2.flags&VAR){
  104.         if(!new->q2.v) ierror(0);
  105.         new->q2.v->flags|=USEDASSOURCE;
  106.         if(code==ADDRESS||(new->q2.flags&VARADR)) new->q2.v->flags|=USEDASADR;
  107.         new->q2.v->priority+=currentpri;
  108.     }
  109.     if(new->z.flags&VAR){
  110.         if(!new->z.v) ierror(0);
  111.         if(new->z.flags&DREFOBJ) new->z.v->flags|=USEDASSOURCE; else new->z.v->flags|=USEDASDEST;
  112.         new->z.v->priority+=currentpri;
  113.     }
  114.     if(/*(c_flags_val[0].l&2)&&*/code==LABEL){
  115.     /*  entfernt Spruenge zu direkt folgenden Labels    */
  116.         struct IC *p=last_ic;
  117.         while(p){
  118.             if(p->typf==new->typf&&p->code>=BEQ&&p->code<=BRA){
  119.                 struct IC *n;
  120.                 if(DEBUG&1) printf("%s l%d deleted\n",ename[p->code],p->typf);
  121.                 n=p->next;
  122.                 remove_IC(p);
  123.                 p=n;
  124.             }else{
  125.                 if(p->code!=LABEL) break;
  126.                 p=p->prev;
  127.             }
  128.         }
  129.     }
  130.     if(last_ic){
  131.         if(code==ASSIGN){
  132.             if((last_ic->z.flags&(REG|SCRATCH|DREFOBJ))==(REG|SCRATCH)&&(new->q1.flags==last_ic->z.flags)&&last_ic->z.reg==new->q1.reg/*&&last_ic->code!=CALL*/){
  133.                 if(USEQ2ASZ||!(last_ic->q2.flags®)||!(new->z.flags®)||last_ic->q2.reg!=new->z.reg){
  134.                     if(USEQ2ASZ||!(last_ic->q2.flags&VAR)||!(new->z.flags&VAR)||last_ic->q2.v!=new->z.v){
  135.                     /*  verbindet op a,b->reg,move reg->c zu op a,b->c  */
  136.                     /*  hier fehlt aber noch Registerfreigabe           */
  137.                         last_ic->z=new->z;
  138.                         if(DEBUG&1) printf("move and op combined\n");
  139.                         if((new->q1.flags&SCRATCH)&&(new->q1.reg!=new->z.reg||!(new->z.flags®)))
  140.                             free_reg(new->q1.reg);
  141.                         free(new);
  142.                         return;
  143.                     }
  144.                 }
  145.             }
  146.             if((last_ic->z.flags&(VAR|SCRATCH|DREFOBJ))==(VAR|SCRATCH)&&(new->q1.flags==last_ic->z.flags)&&last_ic->z.v==new->q1.v/*&&last_ic->code!=CALL*/){
  147.                 if(USEQ2ASZ||!(last_ic->q2.flags®)||!(new->z.flags®)||last_ic->q2.reg!=new->z.reg){
  148.                     if(USEQ2ASZ||!(last_ic->q2.flags&VAR)||!(new->z.flags&VAR)||last_ic->q2.v!=new->z.v){
  149.                     /*  verbindet op a,b->scratch,move scratch->c zu op a,b->c  */
  150.                     /*  hier fehlt aber noch Registerfreigabe           */
  151.                         last_ic->z=new->z;
  152.                         if(DEBUG&1) printf("move and op combined(2)\n");
  153. /*                        if((new->q1.flags&SCRATCH)&&(new->q1.reg!=new->z.reg||!(new->z.flags®)))
  154.                             free_reg(new->q1.reg);*/
  155.                         free(new);
  156.                         return;
  157.                     }
  158.                 }
  159.             }
  160.  
  161.         }
  162.         if(last_ic->code==BRA){
  163.             if(code!=LABEL&&code!=ALLOCREG&&code!=FREEREG){
  164.             /*  loescht alles nach bra bis ein Label kommt  */
  165.             /*  momentan noch nicht perfekt, da es bei alloc/freereg stoppt */
  166.                 free(new);
  167.                 if(DEBUG&1) printf("Unreachable Statement deleted\n");
  168.                 return;
  169.             }
  170.             if(last_ic->prev&&code==LABEL){
  171.             /*  ersetzt bcc l1;bra l2;l1 durch b!cc l2      */
  172.                 if(last_ic->prev->code>=BEQ&&last_ic->prev->code<=BGT&&new->typf==last_ic->prev->typf){
  173.                     if(DEBUG&1) printf("%s l%d;%s l%d; substituted\n",ename[last_ic->prev->code],last_ic->prev->typf,ename[last_ic->code],last_ic->typf);
  174.                     if(last_ic->prev->code&1) last_ic->prev->code--;
  175.                                     else      last_ic->prev->code++;
  176.                     last_ic->prev->typf=last_ic->typf;
  177.                     last_ic=last_ic->prev;
  178.                     free(last_ic->next);
  179.                     last_ic->next=new;new->prev=last_ic;
  180.                     last_ic=new;
  181.                     return;
  182.                 }
  183.             }
  184.         }
  185. /*        }*/
  186.         new->prev=last_ic;
  187.         last_ic->next=new;
  188.         last_ic=new;
  189.     }else{
  190.         last_ic=new;first_ic=new;new->prev=0;
  191.     }
  192.     ic_count++;
  193.     /*  Merken, on Fliesskomma benutzt wurde    */
  194.     if(code!=LABEL&&(code<BEQ||code>BRA)){
  195.         if((new->typf&NQ)==FLOAT||(new->typf&NQ)==DOUBLE) float_used=1;
  196.         if(code==CONVFLOAT||code==CONVDOUBLE) float_used=1;
  197.     }
  198.     if((new->q1.flags&SCRATCH)&&(new->q1.reg!=new->z.reg||!(new->z.flags®)))
  199.         free_reg(new->q1.reg);
  200.     if((new->q2.flags&SCRATCH)&&(new->q2.reg!=new->z.reg||!(new->z.flags®)))
  201.         free_reg(new->q2.reg);
  202. }
  203. void gen_IC(np p,int ltrue,int lfalse)
  204. /*  Erzeugt eine IC-Liste aus einer expression      */
  205. {
  206.     struct IC *new; struct regargs_list *rl;
  207.     if(!p) return;
  208.     if(p->flags==STRING){
  209.     /*  hier fehlt noch die Verwaltung der String-Inhalte   */
  210.         p->o.v=add_var(empty,clone_typ(p->ntyp),STATIC,p->cl);
  211.         p->o.v->flags|=DEFINED;
  212.         p->o.flags=VAR;
  213.         p->o.reg=0;
  214.         p->o.val=p->val;
  215.         return;
  216.     }
  217.     if(p->flags==IDENTIFIER){
  218. /*        p->o.v=find_var(p->identifier,0);*/
  219.         p->o.flags=VAR;
  220.         p->o.reg=0;
  221.         p->o.val=p->val;
  222.         return;
  223.     }